#include ".\print_string_pool.h"
#include "..\critical\critical.h"

#define PRINT_STR_POOL_ITEM_COUNT   2
#if PRINT_STR_POOL_ITEM_COUNT < 1
    #error "PRINT_STR_POOL_ITEM_COUNT < 1"
#endif

#define ALGIN_BYTE  (__alignof__(fsm(print_string)))
#define ALGIN_MASK  ((ALGIN_BYTE) - 1)

static print_str_pool_item_t *s_ptFreeList = NULL;

static uint32_t s_nFreeItemCount = 0;

void print_str_pool_init(void)
{
    s_ptFreeList = NULL;
    s_nFreeItemCount = 0;
}

fsm(print_string) *print_str_pool_allocate(void)
{
    print_str_pool_item_t *ptItem = NULL;

    if (NULL != s_ptFreeList) {
        ptItem = s_ptFreeList;
        s_ptFreeList = s_ptFreeList->ptNext;

        s_nFreeItemCount -= 1;
    }

    return (fsm(print_string) * )ptItem;
}

void print_str_pool_free(fsm(print_string) *ptFsm)
{
    print_str_pool_item_t *ptItem = NULL;

    if (NULL == ptFsm) {
        return ;
    }

    ptItem = (print_str_pool_item_t *)ptFsm;

    ptItem->ptNext = s_ptFreeList;
    s_ptFreeList = ptItem ;

    s_nFreeItemCount += 1;
}

void print_str_pool_extend(void *pMem, uint16_t hwSize)
{
    uint16_t hwElementSize = 0;
    print_str_pool_item_t *ptItem = NULL;

    if ((NULL == pMem) || (hwSize < sizeof(print_str_pool_item_t))) {
        return ;
    }

    ptItem = (print_str_pool_item_t *)pMem;

    while((hwElementSize += sizeof(print_str_pool_item_t)) <= hwSize) {

        print_str_pool_free((fsm(print_string) *)ptItem);

        ptItem += 1;
    }

}

int32_t print_str_pool_count(void)
{
    return s_nFreeItemCount;
}
